"""
Django Models - 数据库模型定义
这个文件定义了数据库表结构，Django 会自动根据这些模型创建数据库表

什么是 Model？
- Model 是 Python 类，代表数据库中的一张表
- 类的属性代表表的字段
- Django ORM（对象关系映射）会自动将 Model 操作转换为 SQL 语句
"""
from django.db import models


class UserNickname(models.Model):
    """
    用户群名片模型
    
    对应数据库表：user_nickname
    这个类定义了：
    - 表名：user_nickname
    - 字段：qq_number, nickname, status, created_at, updated_at
    """
    
    # qq_number 字段：QQ号，整数类型，设置为主键（唯一标识）
    # 主键意味着每条记录都有唯一的QQ号，不能重复
    qq_number = models.BigIntegerField(
        primary_key=True,
        verbose_name='QQ号',
        help_text='用户的QQ号码'
    )
    
    # nickname 字段：群名片，字符串类型，最大长度255
    # null=False 表示不能为空，blank=False 表示表单验证时必须有值
    nickname = models.CharField(
        max_length=255,
        verbose_name='群名片',
        help_text='用户在群中的名片'
    )
    
    # status 字段：状态，整数类型，默认值为1（表示有效）
    # 可以用 1 表示有效，0 表示无效/已删除
    status = models.IntegerField(
        default=1,
        verbose_name='状态',
        help_text='状态：1=有效，0=无效'
    )
    
    # created_at 字段：创建时间，自动记录记录创建的时间
    # auto_now_add=True 表示创建时自动设置当前时间
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间'
    )
    
    # updated_at 字段：更新时间，自动记录记录最后修改的时间
    # auto_now=True 表示每次保存时自动更新为当前时间
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='更新时间'
    )
    
    class Meta:
        """
        Meta 类用于配置 Model 的元数据
        """
        # 数据库表名
        db_table = 'user_nickname'
        
        # 在 Django 管理界面显示的名称
        verbose_name = '用户群名片'
        verbose_name_plural = '用户群名片列表'
        
        # 排序规则：按创建时间倒序（最新的在前）
        ordering = ['-created_at']
    
    def __str__(self):
        """
        返回对象的字符串表示
        用于在 Django 管理界面和调试时显示
        """
        return f"{self.qq_number} - {self.nickname}"


class MessageRecord(models.Model):
    """
    QQ消息记录模型
    
    对应数据库表：message_record
    用于记录QQ群消息和私聊消息
    
    字段说明：
    - qq_message_id: QQ消息的唯一ID（从event.message_id获取）
    - sender_qq: 发送者QQ号
    - group_id: 群号（可为空，私聊时为空）
    - message_type: 消息类型（'group'=群消息，'private'=私聊）
    - message_content: 消息文本内容（提取的纯文本）
    - raw_message: 原始消息JSON（完整保存，用于后续分析）
    - message_time: 消息发送时间（QQ的时间戳）
    - is_recalled: 是否撤回
    - recalled_at: 撤回时间
    - created_at: 记录创建时间（数据库插入时间）
    """
    
    # id 字段：自增主键（Django 默认提供，无需显式定义）
    
    # qq_message_id 字段：QQ消息的唯一ID
    # 注意：QQ消息ID可能不是全局唯一的，所以不作为主键
    qq_message_id = models.BigIntegerField(
        verbose_name='QQ消息ID',
        help_text='QQ消息的唯一标识ID'
    )
    
    # sender_qq 字段：发送者QQ号
    sender_qq = models.BigIntegerField(
        verbose_name='发送者QQ号',
        help_text='发送消息的用户QQ号',
        db_index=True  # 添加索引，方便按发送者查询
    )
    
    # group_id 字段：群号（可为空，私聊时为空）
    group_id = models.BigIntegerField(
        null=True,
        blank=True,
        verbose_name='群号',
        help_text='群号（群消息时有效，私聊时为NULL）',
        db_index=True  # 添加索引，方便按群查询
    )
    
    # message_type 字段：消息类型
    # choices 限制可选值，提高数据一致性
    MESSAGE_TYPE_GROUP = 'group'
    MESSAGE_TYPE_PRIVATE = 'private'
    MESSAGE_TYPE_CHOICES = [
        (MESSAGE_TYPE_GROUP, '群消息'),
        (MESSAGE_TYPE_PRIVATE, '私聊消息'),
    ]
    message_type = models.CharField(
        max_length=10,
        choices=MESSAGE_TYPE_CHOICES,
        default=MESSAGE_TYPE_GROUP,
        verbose_name='消息类型',
        help_text='消息类型：group=群消息，private=私聊消息'
    )
    
    # message_content 字段：消息文本内容
    # 使用TextField存储较长文本，支持存储较长的消息
    message_content = models.TextField(
        verbose_name='消息内容',
        help_text='消息的纯文本内容'
    )
    
    # raw_message 字段：原始消息JSON
    # 完整保存消息对象，用于后续分析、回复等功能
    raw_message = models.JSONField(
        null=True,
        blank=True,
        verbose_name='原始消息',
        help_text='完整的消息对象JSON（用于后续分析）'
    )
    
    # message_time 字段：消息发送时间（QQ的时间戳）
    # 使用DateTimeField存储时间，方便后续查询和排序
    message_time = models.DateTimeField(
        verbose_name='消息时间',
        help_text='消息发送的时间（QQ的时间戳）',
        db_index=True  # 添加索引，方便按时间查询
    )
    
    # is_recalled 字段：是否撤回
    is_recalled = models.BooleanField(
        default=False,
        verbose_name='是否撤回',
        help_text='消息是否已被撤回'
    )
    
    # recalled_at 字段：撤回时间
    recalled_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='撤回时间',
        help_text='消息撤回的时间（如果已撤回）'
    )
    
    # created_at 字段：记录创建时间（数据库插入时间）
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间',
        help_text='记录创建的时间（数据库插入时间）'
    )
    
    class Meta:
        """
        Meta 类用于配置 Model 的元数据
        """
        # 数据库表名
        db_table = 'message_record'
        
        # 在 Django 管理界面显示的名称
        verbose_name = '消息记录'
        verbose_name_plural = '消息记录列表'
        
        # 排序规则：按消息时间倒序（最新的在前）
        ordering = ['-message_time']
        
        # 复合索引：按群号和时间查询（常用查询场景）
        indexes = [
            models.Index(fields=['group_id', 'message_time']),
            models.Index(fields=['sender_qq', 'message_time']),
        ]
    
    def __str__(self):
        """
        返回对象的字符串表示
        用于在 Django 管理界面和调试时显示
        """
        msg_type = '群' if self.message_type == 'group' else '私聊'
        group_info = f"群{self.group_id}" if self.group_id else "私聊"
        return f"[{msg_type}] {group_info} - {self.sender_qq}: {self.message_content[:30]}..."


class Group(models.Model):
    """
    用户分组信息

    用于 `group ls` 命令列出所有可用分组
    """

    name = models.CharField(
        max_length=64,
        unique=True,
        verbose_name='分组标识',
        help_text='命令行中使用的分组名'
    )
    display_name = models.CharField(
        max_length=128,
        blank=True,
        verbose_name='展示名称',
        help_text='可选的友好显示名称'
    )
    description = models.TextField(
        blank=True,
        verbose_name='描述',
        help_text='分组用途说明'
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='创建时间'
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='更新时间'
    )

    class Meta:
        db_table = 'group'
        verbose_name = '分组'
        verbose_name_plural = '分组列表'
        ordering = ['name']

    def __str__(self):
        return self.display_name or self.name


class GroupMember(models.Model):
    """
    分组成员关系

    支持 `group add QQ号 组名` 命令
    """

    group = models.ForeignKey(
        Group,
        to_field='name',
        related_name='members',
        on_delete=models.CASCADE,
        verbose_name='分组',
        db_column='group_name'  # 数据库列名使用 group_name，更直观
    )
    qq_id = models.BigIntegerField(
        verbose_name='QQ号',
        help_text='成员 QQ 号'
    )
    qq_nickname = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='QQ 昵称',
        help_text='成员昵称或群名片'
    )
    added_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='加入时间'
    )

    class Meta:
        db_table = 'group_member'
        verbose_name = '分组成员'
        verbose_name_plural = '分组成员列表'
        unique_together = ('group', 'qq_id')
        indexes = [
            models.Index(fields=['qq_id']),
        ]

    def __str__(self):
        return f"{self.qq_id} @ {self.group.name}"